package com.llu.unsaferadom;

import java.security.SecureRandom;
import java.util.Random;

public class BaseTest {
    public static void main(String[] args) {

        predictRandom();

    }

    /**
     *  不安全的随机数
     */
    public static void unsafeRandom(){
        Random random1 = new Random();
        Random random2 = new Random();
        for (int i = 0; i < 10; i++) {
            System.out.println(random1.nextInt());
//            System.out.println(random2.nextInt());
        }
    }

    /**
     * 安全的随机数
     */
    public static void safeRandom(){
        // 创建一个SecureRandom实例
        SecureRandom secureRandom = new SecureRandom();
        // 可以指定 SecureRandom 使用特定的算法或提供者（Provider）。常见的算法包括 SHA1PRNG、NativePRNG 等。
        // 如果不指定，SecureRandom 将选择平台的默认算法，这通常足够安全。
        //SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");

        // 生成随机整数
        int randomInt = secureRandom.nextInt();
        System.out.println("Random Int: " + randomInt);

        // 生成随机浮点数
        float randomFloat = secureRandom.nextFloat();
        System.out.println("Random Float: " + randomFloat);

        // 生成指定范围内的随机整数 (例如：0到99之间)
        int boundedInt = secureRandom.nextInt(100);
        System.out.println("Bounded Random Int (0-99): " + boundedInt);

        // 生成随机字节数组
        byte[] randomBytes = new byte[16];
        secureRandom.nextBytes(randomBytes);
        System.out.print("Random Bytes: ");
        for (byte b : randomBytes) {
            System.out.printf("%02x ", b);
        }

    }

    /**
     595252840
     -964189397
     -461662482
     -105136343
     1831068880
     883203735
     70696421
     -1257259975
     -284127917
     -1665049006
     */
    public static void predictRandom(){
        // 已知的两个随机数
        int v1 = 595252840;  // 第一个随机数
        int v2 = -964189397;  // 第二个随机数

        // LCG 参数
        long multiplier = 25214903917L;
        long addend = 11L;
        long mask = (1L << 48) - 1;

        // 枚举所有可能的高16位
        for (long highBits1 = 0; highBits1 < (1L << 16); highBits1++) {
            long r1_candidate = ((long) v1 << 16) | highBits1;
            long r2_candidate = (r1_candidate * multiplier + addend) & mask;

            // 检查这个候选的内部状态是否能生成第二个随机数
            if (v2 == (int) (r2_candidate >>> 16)) {
                System.out.println("Possible r1_candidate: " + r1_candidate);

                // 用这个r1_candidate创建一个新的Random对象
                Random rand = new Random(r1_candidate);

                // 验证它生成的后续随机数是否与已知的随机数匹配
                int v1_test = rand.nextInt();
                int v2_test = rand.nextInt();

                // 如果匹配，说明这个种子是正确的
                if (v1_test == v1 && v2_test == v2) {
                    System.out.println("Found matching seed! r1: " + r1_candidate);
                    System.out.println("Predicted next random number: " + rand.nextInt());
                    break; // 可以停止搜索，也可以继续查找其他可能的候选种子
                }
            }
        }
    }
}
